﻿using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.DynamicData;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using NotAClue.ComponentModel.DataAnnotations;
using NotAClue.Web;
using NotAClue.Web.DynamicData;

namespace DD_Extensions
{
    public partial class FileUpload_EditField : FieldTemplateUserControl
    {
        private FileUploadAttribute fileUploadAttribute;
        private String primaryKeyValue;
        public override Control DataControl
        {
            get { return Label1; }
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            // add tool-tip
            this.SetupTip();

            // set field options
            this.SetFieldOptions();

            // add CSS from meta data
            this.ApplyCss();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // get attributes
            fileUploadAttribute = MetadataAttributes.GetAttributeOrDefault<FileUploadAttribute>();
            if (fileUploadAttribute == null)
                throw new InvalidOperationException("FileUpload must have valid FileUploadAttribute applied");
            else
                FileUpload1.ToolTip = String.Format("Upload {0} files", fileUploadAttribute.FileTypeString());

            // get primary key value
            primaryKeyValue = Table.GetPrimaryKeyValuesAsString(Page);

            if (Column.IsRequired)
                FileUpload1.CssClass += " RequiredField";

            CustomValidator1.Text = "*";
            SetUpValidator(CustomValidator1);

            // set validators to use image as error indicator
            this.SetValidatorsToImage();

            if (Column.IsRequired)
                FileUpload1.CssClass += " DDRequired";
        }

        protected void CustomValidator1_ServerValidate1(object source, ServerValidateEventArgs args)
        {
            var extensions = fileUploadAttribute.FileTypes;

            if (FileUpload1.HasFile)
            {
                // get files name
                var fileName = FileUpload1.FileName;

                // get files extension without the dot
                String fileExtension = fileName.Substring(fileName.LastIndexOf(".") + 1).ToLower();

                // check file has an allowed file extension
                if (!extensions.Contains(fileExtension))
                {
                    args.IsValid = false;
                    CustomValidator1.ErrorMessage = String.Format("{0} is not a valid file to upload", FileUpload1.FileName);
                }
            }
            else if (Column.IsRequired && String.IsNullOrEmpty(Label1.Text))
            {
                args.IsValid = false;
                CustomValidator1.ErrorMessage = Column.RequiredErrorMessage;
            }
        }

        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);

            //check if field has a value
            if (FieldValue == null)
                return;

            // when there is already a value in the FieldValue
            // then show the icon and label/hyperlink
            PlaceHolder1.Visible = true;

            // get the file extension
            String extension = FieldValueString.Substring(
                FieldValueString.LastIndexOf(".") + 1,
                FieldValueString.Length - (FieldValueString.LastIndexOf(".") + 1));

            String displayImageUrl = fileUploadAttribute.DisplayImageUrl;
            String displayImageType = fileUploadAttribute.DisplayImageType;
            String filePath;

            // check the file exists else throw validation error
            if (fileUploadAttribute != null)
                filePath = UploadExtensionMethods.GetUploadPath(fileUploadAttribute.FileUploadPath, Table.Name, primaryKeyValue, Column.Name) + FieldValueString;
            else
                throw new InvalidOperationException("An FileUploadPath is required for the FileUpload FieldTemplate to work");

            // check file exists on file system
            if (!File.Exists(Server.MapPath(filePath)))
            {
                CustomValidator1.ErrorMessage = String.Format("{0} does not exist", FieldValueString);
                CustomValidator1.IsValid = false;
            }

            // if either hyperlinks are disabled or the 
            // file does not exist then hide the link
            if (fileUploadAttribute.DisableHyperlink || !File.Exists(Server.MapPath(filePath)))
            {
                Label1.Text = FieldValueString;
                HyperLink1.Visible = false;
            }
            else
            {
                Label1.Visible = false;
                // Target="_blank" 
                HyperLink1.Target = fileUploadAttribute.OpenInNewWindow ? "_blank" : String.Empty;
                HyperLink1.Text = FieldValueString;
                HyperLink1.NavigateUrl = filePath;
            }

            // show the icon
            if (!String.IsNullOrEmpty(extension))
            {
                // set the file type image
                if (!String.IsNullOrEmpty(displayImageUrl))
                {
                    Image1.ImageUrl = String.Format(displayImageUrl, extension + "." + displayImageType);
                }
                else
                {
                    // if attribute not set the use default
                    Image1.ImageUrl = String.Format("~/images/{0}", extension + "." + displayImageType);
                }

                Image1.AlternateText = extension + " file";

                // if you apply dimensions from DD Futures
                var imageFormat = MetadataAttributes.GetAttribute<ImageFormatAttribute>();
                if (imageFormat != null)
                {
                    // if either of the dims is 0 don't set it
                    // this will mean that the aspect will remain locked
                    if (imageFormat.DisplayWidth != 0)
                        Image1.Width = imageFormat.DisplayWidth;
                    if (imageFormat.DisplayHeight != 0)
                        Image1.Height = imageFormat.DisplayHeight;
                }
            }
            else
            {
                // if file has no extension then hide image
                Image1.Visible = false;
            }
        }

        protected override void ExtractValues(IOrderedDictionary dictionary)
        {
            String fileUrl;
            String[] extensions;
            if (fileUploadAttribute != null)
            {
                fileUrl = fileUploadAttribute.FileUploadPath;
                extensions = fileUploadAttribute.FileTypes;

                if (FileUpload1.HasFile)
                {
                    // get the file full path
                    String uploadDir = UploadExtensionMethods.GetUploadPath(fileUploadAttribute.FileUploadPath, Table.Name, primaryKeyValue, Column.Name);

                    // resolve full path c:\... etc
                    String filePath = Server.MapPath(uploadDir);

                    // get files extension without the dot
                    //String fileExtension = FileUpload1.FileName.Substring(
                    //    FileUpload1.FileName.LastIndexOf(".") + 1).ToLower();
                    String fileExtension = FileUpload1.FileName.GetFileExtension();

                    // check file has an allowed file extension
                    if (extensions.Contains(fileExtension))
                    {
                        // try to upload the file showing error if it fails
                        try
                        {
                            var dirInfo = new DirectoryInfo(filePath);
                            // make sure the folder exists
                            if (!dirInfo.Exists)
                                dirInfo.Create();

                            // delete files in upload folder
                            if (Mode == DataBoundControlMode.Edit)
                                dirInfo.DeleteAllFilesInDirectory();

                            // save the file
                            FileUpload1.SaveAs(filePath + FileUpload1.FileName);

                            // save filename
                            dictionary[Column.Name] = FileUpload1.FileName;
                        }
                        catch (Exception)
                        {
                            dictionary[Column.Name] = null;
                        }
                    }
                    else
                    {
                        dictionary[Column.Name] = null;
                    }
                }
                else if (!String.IsNullOrEmpty(Label1.Text))
                {
                    dictionary[Column.Name] = Label1.Text;
                }
                else
                {
                    // return null if no file or ImageUrlAttribute is null or empty
                    dictionary[Column.Name] = null;
                }
            }
        }
    }
}